define([], function() {
    'use strict';
    /**
     * 树形结构表格渲染
     * @param {*} option 
     * @param id - 容器id
     * @param columns - 显示的表头信息
     * @param treeData - 要显示的树形数据
     * @param lastMode - 最后一级显示的方式 horizontal-横向(默认) vertical-纵向
     * @param key - 判断是否选中的唯一值，默认为name
     * @param showKey - 显示的键名，默认为name
     * @param titleFixed - 标题是否固定，默认为false
     * @param selectKeys - 选中的key值的list，默认为[]
     * @param showTips - 是否显示表格顶部的标识框
     * @param tipsMsg - 表格顶部标识左侧可以显示的信息
     * @param checkAll - 选中所有的选项
     * @param showLast - 树形的最后一级是否显示在最后一列，true-会自动显示在最后一行，false，按照层级一层一层的显示
     */
    function TreeTable(option){
        if(!option.id){
            throw new Error('缺少必填项，容器id');
        }
        this.boxId = option.id;
        this.columns = option.columns || [];
        this.key = option.key || 'name';
        this.showKey = option.showKey || "name";
        this.titleFixed = !option.titleFixed ? false : true;
        this.selectKeys = option.selectKeys || [];
        this.showTips = !option.showTips ? false : true;
        this.checkAll = !option.checkAll ? false : true;
        this.tipsMsg = option.tipsMsg || "";
        this.maxLevel = !option.columns ? 0 : option.columns.length;
        // this.box = document.getElementById(this.boxId);
        // this.box.className = 'yby-tree-table';
        this.box = $("#" + this.boxId);
        this.box.addClass("yby-tree-table");
        this.treeData = option.treeData || [];
        this.lastMode = option.lastMode || "horizontal";
        this.showLast = !option.showLast ? false : true;
        this.init();
    }

    /**
     * 初始化方法
     */
    TreeTable.prototype.init = function(){
        var flag = this.maxLevel > 0 ? true : false;
        this.changeSelectKeys();
        var aList = this.preCheck(this.treeData, false, 1);
        this.list = this.getList(aList, flag);
        this.listData = [];
        if(!this.showLast){
            this.reGroupList_new(this.list, {});
        }else{
            this.reGroupList(this.list, {});
        }
        console.log('this.list', this.list);
        console.log('this.listData', this.listData);
        this.renderHtml();
    }

    TreeTable.prototype.changeSelectKeys = function(){
        var obj = {};
        this.selectKeys.forEach(function(item){
            if(!item || (typeof item != 'string' && typeof item != "number")){
                return;
            }else{
                obj[item] = true;
            }
        })
        this.selectKeysObj = obj;
    }

    /**
     * 复制简单的一级对象
     */
    TreeTable.prototype.copyObj = function(target){
        var obj = {};
        for(var key in target){
            obj[key] = target[key];
        }
        return obj;
    }

    /**
     * @param target - 需要组装的对象
     * @param item - 需要组装的item
     * @param flag - item所在的层级是否是最后一级
     */
    TreeTable.prototype.reGrouopObj = function(target, item, flag){
        var that = this;
        var obj = this.copyObj(target);
        var aItem = this.copyObj(item);
        // 当最后一级渲染模式为纵向或者当前item.children不是最后一级
        if(this.lastMode == "vertical" || !that.isLastLevel(item.children)){
            aItem.children = '';
        }
        // 当是最后一级且level不是第一层的时候
        if(flag && aItem.level != 1){
            // 为了补全中间缺少的层级
            for(var i = aItem.level;i < that.maxLevel;i++){
                obj[i] = { rows:aItem.rows, name:"" };
            }
            obj[that.maxLevel] = aItem;
        }else{
            if(aItem && !!aItem.level){
                obj[aItem.level] = aItem;
            }
            // item.chilren是最后一级，lastMode为horizontal
            if(this.lastMode == "horizontal" && aItem.children && aItem.children.length > 0 && that.isLastLevel(aItem.children)){
                for(var i = aItem.level + 1;i < that.maxLevel;i++){
                    obj[i] = { rows:aItem.rows, name:"" };
                }
                obj[that.maxLevel] = { name: "", rows: 1, children: aItem.children };
            }
        }
        return obj;
    }

    /**
     * 如果list为最后一级并且level不为1的时候，level归为maxLevel
     * @param list - 需要组装的数据
     * @param obj - 上一级的数据，仅供下级list的第一个用，其他的为{}
     */
    TreeTable.prototype.reGroupList = function(list, obj){
        var that = this;
        var flag = this.isLastLevel(list);// list是否是最后一级
        list.forEach(function(item, index){
            var aObj = that.reGrouopObj(index > 0 ? {} : obj, item, flag);
            // 此次循环的children是否是最后一级，需要横向展示
            var aFlag = that.getFlag(item);
            if(item.children && item.children.length > 0 && !aFlag){
                that.reGroupList(item.children, aObj);
            }else{
                that.listData.push(aObj)
            }
        })
    }

    /**
     * @param target - 需要合并的obj
     * @param item - 遍历的item
     * @param flag - 是否是最后一级
     */
    TreeTable.prototype.reGroupObj_new = function(target, item, flag){
        var that = this;
        var obj = this.copyObj(target);
        var aItem = this.copyObj(item);
        if(that.lastMode == "vertical"){
            obj[aItem.level] = aItem;
        }else{
            if(!flag){
                obj[aItem.level] = aItem;
            }else{
                obj[aItem.level] = aItem;
                obj[that.maxLevel] = { name: "", rows: 1, children: aItem.children };
            }
        }
        return obj;
    }

    TreeTable.prototype.reGroupList_new = function(list, obj){
        var that = this;
        list.forEach(function(item, index){
            if(that.lastMode == "vertical"){
                var aFlag = item.level < that.maxLevel ? false : true;
                var aObj = that.reGroupObj_new(index > 0 ? {} : obj, item, aFlag);
                if(item.children && item.children.length > 0 && !aFlag){
                    that.reGroupList_new(item.children, aObj);
                }else{
                    that.listData.push(aObj);
                }
            }else{
                var aFlag = item.level < that.maxLevel - 1 ? false : true;
                var aObj = that.reGroupObj_new(index > 0 ? {} : obj, item, aFlag);
                if(item.children && item.children.length > 0 && !aFlag){
                    that.reGroupList_new(item.children, aObj);
                }else{
                    if(item.level < that.maxLevel){
                        that.listData.push(aObj);
                    }
                }
            }
        })
    }

    /**
     * 提前检验是否选中
     * @param list - 树形数据
     * @param checked - 上级节点是否选中
     * @param level - 当前节点的层级，从1开始
     */
    TreeTable.prototype.preCheck = function(list, checked, level){
        checked = !checked ? false : true;
        var that = this;
        var aList = list.map(function(item){
            var aChecked = !that.selectKeysObj[item[that.key]] ? checked : true;
            if(item.children && item.children.length > 0){
                item.children = that.preCheck(item.children, aChecked, level + 1);
                var isCheck = false, checkAll = true;
                item.children.forEach(function(e){
                    isCheck = e.checkedStyle != "check-no" ? true : isCheck;
                    checkAll = e.checkedStyle != "check-all" ? false : checkAll;
                })
                item.checkedStyle = that.checkAll ? "check-all" : !isCheck ? "check-no" : checkAll ? 'check-all' : 'check-half';
            }else{
                item.checkedStyle = that.checkAll || aChecked ? "check-all" : 'check-no';
            }
            item.level = level;
            return item;
        })
        return aList;
    }

    TreeTable.prototype.getFlag = function(item){
        var aFlag;
        if(this.showLast){
            aFlag = this.lastMode == "vertical" ? false : this.isLastLevel(item.children);
        }else{
            aFlag = this.lastMode == "vertical" ? false : item.level < this.maxLevel ? false : this.isLastLevel(item.children);
        }
        return aFlag;
    }

    /**
     * 根据传入的数据和columns数据进行数据重组装
     * @param list - 需要组装的数据
     * @param flag - 是否设定columns
     */
    TreeTable.prototype.getList = function(list, flag){
        var that = this;
        var aList = list.map(function(item){
            // 最后一级下沉至最后一列显示
            if(that.showLast){
                // 此处最后一层如果是横向展示的时候，需要判断当前的item.children是否是最后一层
                var aFlag = that.getFlag(item);
                if(item.children && item.children.length > 0 && !aFlag){
                    item.children = that.getList(item.children, flag);
                    var rows = 0;
                    item.children.forEach(function(e){
                        rows += e.rows;
                    })
                    item.rows = rows;
                }else{
                    item.rows = 1;
                }
                if(!flag){// 当没有设定columns的时候，自己计算出数据最大的层级
                    that.maxLevel = that.maxLevel < item.level ? item.level : that.maxLevel;
                }
            }else{
                // 最后一级显示在本来的列上
                if(that.lastMode == "vertical"){
                    if(item.level < that.maxLevel && item.children && item.children.length > 0){
                        item.children = that.getList(item.children, flag);
                        var rows = 0;
                        item.children.forEach(function(e){
                            rows += e.rows;
                        })
                        item.rows = rows;
                    }else{
                        item.rows = 1;
                    }
                }else{
                    if(item.level < that.maxLevel - 1 && item.children && item.children.length > 0){
                        item.children = that.getList(item.children, flag);
                        var rows = 0;
                        item.children.forEach(function(e){
                            rows += e.rows;
                        })
                        item.rows = rows;
                    }else{
                        item.rows = item.level < that.maxLevel ? 1 : 0;
                    }
                }
            }
            return item;
        })
        return aList;
    }

    /**
     * 获取colgroup的col
     */
    TreeTable.prototype.getCols = function(total){
        var index = this.columns.length - total;
        var str = '';
        this.columns.forEach(function(item, aIndex){
            str += index <= aIndex ? '<col width="'+ item.width +'">' : '';
        })
        return str;
    }

    /**
     * 获取total个空td
     */
    TreeTable.prototype.getTds = function(total){
        var str = '';
        for(var i = 0;i < total;i++){
            str += '<td></td>';
        }
        return str;
    }

    /**
     * 判断list是否是最后一级
     */
    TreeTable.prototype.isLastLevel = function(list){
        var flag = true;
        if(!list){
            return flag;
        }
        list.forEach(function(item){
            if(item.children && item.children.length > 0){
                flag = false;
            }
        })
        return flag;
    }

    TreeTable.prototype.getBtns = function(list){
        var that = this;
        if(!list && list.length == 0){
            return '<span></span>';
        }
        var str = '';
        list.forEach(function(item, index){
            str += '<span class="btn-cell '+ item.checkedStyle +'">'+ item[that.showKey] +'</span>';
        })
        return str;
    }

    /**
     * 渲染body的tr
     */
    TreeTable.prototype.renderTr = function(data){
        var that = this;
        var str = '';
        var flag = false;
        this.columns.forEach(function(item, index){
            var aData = !data || !data[index+1] ? {} : data[index+1];
            flag = !data || !data[index + 1] ? flag : true;// 为了解决没有按钮的显示问题
            if(index + 1 == that.maxLevel && that.lastMode == "horizontal"){
                str += '<td>'+ that.getBtns(aData.children || []) +'</td>';
            }else{
                str += !aData.rows ? !flag ? '' : '<td></td>' : '<td rowspan="'+ aData.rows +'"><span class="btn-cell '+ aData.checkedStyle +'">'+ (aData[that.showKey] || '') +'</span></td>';
            }
        })
        return str;
    }

    /**
     * 渲染表格
     */
    TreeTable.prototype.renderHtml = function(){
        var that = this;
        var str_col = this.getCols(this.maxLevel);
        var str_th = '';
        if(this.columns && this.columns.length > 0){
            this.columns.forEach(function(item){
                str_th += '<th>'+ item.title +'</th>';
            })
        }else{
            for(var i = 0;i < this.maxLevel;i++){
                str_th += '<th>title'+ (i + 1) +'</th>';
            }
        }

        var str_content = '';
        this.listData.forEach(function(item){
            str_content += '<tr>'+ that.renderTr(item) +'</tr>';
        })

        var tableStr = {
            colStr: '<colgroup>'+ str_col +'</colgroup>',
            thead: '<thead><tr>'+ str_th +'</tr></thead>',
            tbody: '<tbody>'+ str_content +'</tbody>'
        }

        var str = '';
        if(this.showTips){
            str = '<div class="top-title-box">'
                + '<div class="top-title-left">'+ this.tipsMsg +'</div>'
                + '<div class="top-title-right">'
                + '<span class="btn-cell check-all">全选</span>'
                + '<span class="btn-cell check-half">未全选</span>'
                + '<span class="btn-cell check-no">未选</span>'
                + '</div>'
                + '</div>'
        }
        if(this.titleFixed){
            str += '<div class="table-box fixed">'
                + '<div class="fixed-title"><table>' + tableStr.colStr + tableStr.thead + '</table></div>'
                + '<div class="fixed-body" style="max-height:'+ (this.height || 300) +'px;overflow-y:auto;"><table>' + tableStr.colStr + tableStr.tbody + '</table></div>'
                + '</div>';
        }else{
            str += '<div >'
                + '<table class="table-box">' + tableStr.colStr + tableStr.thead + tableStr.tbody + '</table>'
                + '</div>';
        }
        this.box.html(str);
    }

    return TreeTable;
});